#include "stm32f1xx_hal.h"
#include <stdio.h>
#include "bsp_usart.h"
#include "oled.h"
#include "esp8266.h"
UART_HandleTypeDef huartx; // 串口1
UART_HandleTypeDef huarty; // 串口2
static uint8_t uartRxByte; // 全局接收
DMA_HandleTypeDef g_dma_handle3;

UARTy_dma_buf g_UARTy_dma_buf_t = {0};

// 串口重定向
int fputc(int ch, FILE *f)
{

    HAL_UART_Transmit(&huarty, (uint8_t *)&ch, 1, 0xffff);
    return ch;
}



void led_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOE_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);


     GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);
}
uint8_t Key_Scan(void)
{
    static uint8_t key_state = 0;
    switch (key_state)
    {
        case 0:  // 等待按下
            if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)
            {
                key_state = 1;
            }
            
            break;
        case 1:  // 消抖
            HAL_Delay(10);
            if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)
            {
                key_state = 2;
                HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);
                esp8266_send_cmd("AT+MQTTPUB=0,\"/sys/k01r6CbeVML/esp-01/thing/event/property/post\",\"{params:{LEDSwitch:1}}\",1,0",3,1000);
               
                return 1;  
            }
            else
            {
                key_state = 0;
            }
            break;
        case 2:  // 等待松开
            if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_SET)
            {
                HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
                 esp8266_send_cmd("AT+MQTTPUB=0,\"/sys/k01r6CbeVML/esp-01/thing/event/property/post\",\"{params:{LEDSwitch:0}}\",1,0",3,1000);
                key_state = 0;
            }
            break;
    }
    return 0;
}



// USART1
void bsp_usart1_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    USARTx_CLK_ENABLE();

    // 配置TX引脚
    GPIO_InitStruct.Pin = USARTx_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

    // 配置RX引脚
    GPIO_InitStruct.Pin = USARTx_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

    huartx.Instance = USART1;
    huartx.Init.BaudRate = 115200;
    huartx.Init.WordLength = UART_WORDLENGTH_8B;
    huartx.Init.StopBits = UART_STOPBITS_1;
    huartx.Init.Parity = UART_PARITY_NONE;
    huartx.Init.Mode = UART_MODE_TX_RX;
    huartx.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huartx.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huartx) != HAL_OK)
    {
        Error_Handler();
    }

    // 打开串口中断
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
    HAL_UART_Receive_IT(&huartx, &uartRxByte, 1); // 开启接收
}

void bsp_usart3_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOB_CLK_ENABLE();
    USARTy_CLK_ENABLE();
    
    __HAL_RCC_DMA1_CLK_ENABLE();   // DMA1使能 
    
    // 配置TX引脚
    GPIO_InitStruct.Pin = USARTy_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(USARTy_TX_GPIO_PORT, &GPIO_InitStruct);

    // 配置RX引脚
    GPIO_InitStruct.Pin = USARTy_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(USARTy_RX_GPIO_PORT, &GPIO_InitStruct);

    huarty.Instance = USART3;
    huarty.Init.BaudRate = 115200;
    huarty.Init.WordLength = UART_WORDLENGTH_8B;
    huarty.Init.StopBits = UART_STOPBITS_1;
    huarty.Init.Parity = UART_PARITY_NONE;
    huarty.Init.Mode = UART_MODE_TX_RX;
    huarty.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huarty.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huarty) != HAL_OK)
    {
        Error_Handler();
    }
    
    // 修改DMA配置部分
    g_dma_handle3.Instance = DMA1_Channel3;                      // USART3_RX使用DMA1通道3
    g_dma_handle3.Init.Direction = DMA_PERIPH_TO_MEMORY;         // 外设到存储器
    g_dma_handle3.Init.PeriphInc = DMA_PINC_DISABLE;             // 外设非增量模式
    g_dma_handle3.Init.MemInc = DMA_MINC_ENABLE;                 // 存储器增量模式
    g_dma_handle3.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // 外设数据长度:8位
    g_dma_handle3.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;    // 存储器数据长度:8位
    g_dma_handle3.Init.Mode = DMA_NORMAL;                        // 普通模式(非循环)
    g_dma_handle3.Init.Priority = DMA_PRIORITY_MEDIUM;           // 中等优先级
    
    if (HAL_DMA_Init(&g_dma_handle3) != HAL_OK)
    {
        Error_Handler();
    }
    
    // 关联DMA到UART
    __HAL_LINKDMA(&huarty, hdmarx, g_dma_handle3);
    
    // 打开串口中断
    __HAL_UART_ENABLE_IT(&huarty, UART_IT_IDLE); 
    HAL_NVIC_SetPriority(USART3_IRQn, 0, 1);
    HAL_NVIC_EnableIRQ(USART3_IRQn);

    // 启动DMA接收
    HAL_UART_Receive_DMA(&huarty, (uint8_t *)g_UARTy_dma_buf_t.uart3Rxbuf, sizeof(g_UARTy_dma_buf_t.uart3Rxbuf));
}

void Error_Handler(void)
{
    while (1)
        ;
}

// 中断服务程序
void USART1_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huartx);
}

// 中断服务程序
void USART3_IRQHandler(void)
{

    if(__HAL_UART_GET_FLAG(&huarty, UART_FLAG_IDLE))
    {
        __HAL_UART_CLEAR_IDLEFLAG(&huarty);
       HAL_UART_DMAStop(&huarty);
        // 计算接收到的数据长度
        g_UARTy_dma_buf_t.uart3RxLen = sizeof(g_UARTy_dma_buf_t.uart3Rxbuf) - __HAL_DMA_GET_COUNTER(huarty.hdmarx);
        
        if(g_UARTy_dma_buf_t.uart3RxLen > 0)
        {
            g_UARTy_dma_buf_t.g_state_flag = 1;
        }
        // 重新启动DMA接收
        HAL_UART_Receive_DMA(&huarty, (uint8_t *)g_UARTy_dma_buf_t.uart3Rxbuf, sizeof(g_UARTy_dma_buf_t.uart3Rxbuf));
    }
    HAL_UART_IRQHandler(&huarty);

}

// 接收完成回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    static uint8_t p0 = 0, p1 = 0;

    if (huart == &huartx)
    {
        /*将一个字节放到OLED显存数组的指定位置*/
        OLED_DisplayBuf[p0][p1] = uartRxByte;
        /*位置自增*/
        p1++;
        if (p1 >= 128)
        {
            p1 = 0;
            p0++;
            if (p0 >= 8)
            {
                p0 = 0;
            }
        }

        // 重新启动接收中断，准备接收下一个字节
        HAL_UART_Receive_IT(&huartx, (uint8_t *)&uartRxByte, 1);
    }
    
}
